(DemoLib@#WireListWindow) metaclass description: (Text from: 'This is the UIWindow to support the WireListModel demo. It works together with WireList (a subclass if List), and WireListModel (a subclass of ApplicationModule).' styleRuns:((ScrapStyle basicNew: 0) storageSize: 22; storageFromHexString: '000100000000000C000A000100000009000000000000'))!
(DemoLib@#WireListWindow methodAt: #'createWindow') description: ('createWindow is called by the open message, UIWindow>>open. This open message is sent when the application is launched; see WIreListModel>>launch.').!
DemoLib@#WireListWindow compileMethodSource: (
Text from: 'dimensionsChangedFrom: oldBounds to: newBounds
| “Local (Method Scope) Variables Are Declared Here” |
“This method is needed force updating of the graphic region on resizing. It is not normally
required in cases where the graphic region is a GraphicPane”
%% “Begin Compiler Directives”
%
% Method Author: ‘peskin’.
% Method Created: ‘Thu 07/22/1993 12:58:14 PM’.
%
% Private Method. “Use "Ensure Private Method" To Force Checking”
% Method Protocol: nil.
%
% Method Description: ''Special method for WireListModel demo; not normally needed. It is
used to update a frame. Normally this will be taken care of in
component updates (see DESolverWIndow example) ''.
(DemoLib@#WireListWindow methodAt: #'dimensionsChangedFrom:to:') description: ('Special method for WireListModel demo; not normally needed. It is used to update a frame. Normally this will be taken care of in component updates (see DESolverWIndow example)').!
DemoLib@#WireListWindow compileMethodSource: (
Text from: 'privateSelfRender: dirtyArea in: gPort color: isColor depth: pixelDepth
"These first lines are boiler plate to avoid unnessessary redrawing of static component regions"
(DemoLib@#WireListWindow methodAt: #'privateSelfRender:in:color:depth:') description: ('Called on every update by superclass (UIWindow) methods. THIS METHOD MUST BE DEFINED FOR YOUR APPLICATION WINDOW, OTHERWISE YOU WILL GET A DEFAULT WINDOW.').!
DemoLib@#WireListWindow compileMethodSource: (
Text from: 'shorten
"Call the algorithms in WireList class to compute the new length"
module wires shorten.
"info is an instance variable of WIreListWindow; it is assigned as a StaticTextField in the
createWindow method. Here we update the string to be put in that StaticTextField. This may
appear to be a duplication of action by #buttonDown, but this is needed because we have to
update this message when we both add points and shorten wires"
info contents: (''Length of wire is: '',((module wires length) printFormatted: ''%12.4f''),''.'').
"Now mark the view dirty so the new wires can be drawn"
(DemoLib@#WireListWindow methodAt: #'shorten') description: ('Called when you press the [shorten wire] button. This calls the algorithmic methods that compute the new (reduced) wire length. These algorithms are in the WireList class').!
DemoLib@#WireListWindow compileMethodSource: (
Text from: 'updateInfo: length
info contents: (''Length of wire is: '',(length printFormatted: ''%12.4f''),''.'').
(DemoLib@#WireListWindow methodAt: #'drawWindowContents') description: ('Called this from privateSelfRender::: It calls the method that actually draws the wires based on the contents of the WireList.').!
DemoLib@#WireListWindow compileMethodSource: (
Text from: ' buttonDown
"This method will control adding and moving of points in the display and updating of the
WireList"
| p p2 indx dist tmp w pBnds |
"Set up a copy of the bounds; a safe thing to do because many bounds methods are destructive"
pBnds := self windowPort bounds.
"This is the point where you pressed the button"
p := Mouse localPosition.
"We will restrict the region where we can add points to inside a Rectangle (black frame)"
((Rectangle top: pBnds top + 34 left: pBnds left + 14 bottom: pBnds bottom -14
right: pBnds right - 14 ) containsPoint: p) ifTrue: [
w := module wires. "This is a temporary of the WireList"
indx := 0.
dist := 5. "Magic number here is just the diameter of circle we draw at selected points"
"For each entry in the WireList, measure its distance to p. If any point is closer than 5 to p
consider p and that point to be the same."
1 to: (w size) do: [ :i |
tmp := w distance: i to: p.
(tmp < dist)
ifTrue: [ dist := tmp. indx := i ].
].
"Otherwise, add the point to the list and update the current length message, draw the new point
and connect it to the either the last one drawn, or change its location"
(indx > 0)
ifFalse: [
module add: p.
self updateInfo: (w length).
self markAsDirty. "Mark the window so that we can update the drawing in it."
^nil
].
w drawRubberBandWith: indx on: (self windowPort). "Either draw a new section or rubber band
to a new position"
]
ifFalse: [Speakers beep]. "Tried to place a point outside the frame!!"
p2 := Mouse localPosition. "This is the position resulting from dragging the mouse during rubber
banding"
((Rectangle top: pBnds top + 34 left: pBnds left + 14 bottom: pBnds bottom -14
right: pBnds right - 14 ) containsPoint: p2) ifTrue: [ "is it in the frame?"
w at: indx put: p2. "Change the point location value at that index in the list"
self updateInfo: (w length). "update the length message in the window"
self markAsDirty. "Make sure we can draw in the relocated point and connect it"
]
ifFalse: [Speakers beep]. "Tried to move it outside the frame"
"NOTES: We purposely do not erase the rubber band lines if you try to go outside the frame.
This way the user can see where he/she came from and either add a new point or
recover the prior position.
The drawRubberBand method draws the temporary relocation picture, but the
(DemoLib@#WireListWindow methodAt: #'buttonDown') description: ('Determines the actions to be taken when the user presses the mouse button in the main pane area (area exclusive of special components).').!
DemoLib@#WireListWindow compileMethodSource: (
Text from: 'commandTyped
"Takes string (str) from the text input field (TEField) and evaluates it. Useful for learning
and debugging. Try typing in [inspect] or [modules inspect]"